home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1997 February / PC Plus Super CD (Issue 124) (PCP124-2-97) (February 1997).iso / componen / m4 / ace.kb < prev    next >
Encoding:
Text File  |  1996-01-12  |  18.4 KB  |  680 lines

  1. /*
  2.   This is a small kb to experiment with object-oriented
  3.   programming in M1.
  4. */
  5.  
  6. /*
  7.  9/90 -- This is a small kb to illustrate the use of object-
  8.  oriented programming.  The domain is planes and flying.  This
  9.  was chosen to reflect a number of the examples in the M.1 v3
  10.  documentation.  The main procedure is 'simulate', which allows
  11.  you to select a plane and then execute various actions
  12.  (load, unload, take-off, fly, etc.).
  13.  
  14.  11/90 -- Modified kb to make it clearer from a user's
  15.  perspective.  One speed is asked, instead of x- and y-
  16.  velocities.  Expressions that might need to be asked a number of
  17.  times (for repeated actions) are nocache.
  18.  - To be robust, all expressions should have some default.
  19.  There should be some 'common sense' rules, such as checking
  20.  for reasonable speeds, altitudes, etc.  For example, it doesn't
  21.  make sense to fly or descent if you're on the ground; you
  22.  shouldn't be able to go to a negative altitude...
  23.  - There are places that I've put NOTES for a future developer--
  24.  they should be read and removed before this is made a sample kb.
  25.  
  26.  */
  27.  
  28. initialdata = [welcome, simulate].
  29.  
  30. /*------------------ Class and Instance Definitions ---------*/
  31.  
  32. classdef(moving_object) = [
  33.    supers = [],
  34.    x_position = 0,
  35.    y_position = 0,
  36.    x_velocity = 0,
  37.    y_velocity = 0
  38.    ].
  39.  
  40. classdef(means_of_transportation) = [
  41.    supers = [],
  42.    arrival_time,
  43.    departure_time,
  44.    carrying_capacity,
  45.    fuel_capacity
  46.    ].
  47.  
  48. classdef(airplane) = [
  49.    supers = [moving_object, means_of_transportation],
  50.    airplane_id_number,
  51.    name,
  52.    altitude = 0
  53.    ].
  54.  
  55. classdef(passenger_plane) = [
  56.    supers = [airplane],
  57.    number_of_passengers = 0,
  58.    passenger_capacity
  59.    ].
  60.  
  61. classdef(cargo_plane) = [
  62.    supers = [airplane],
  63.    tonnage_capacity,
  64.    cargo = []
  65.    ].
  66.  
  67. /* A few instances */
  68. instdef(anemone) = [
  69.    class = passenger_plane,
  70.    passenger_capacity = 120,
  71.    name = "anemone"
  72.    ].
  73.  
  74. instdef(urchin) = [
  75.    class = passenger_plane,
  76.    passenger_capacity = 80,
  77.    name = "urchin"
  78.    ].
  79.  
  80. instdef(sea_spray) = [
  81.    class = cargo_plane,
  82.    name = sea_spray
  83.    ].
  84.  
  85. instdef(sea_breeze) = [
  86.    class = cargo_plane,
  87.    name = sea_breeze
  88.    ].
  89.  
  90. /*-------------------- add_list -------------------------*/
  91. add_list(CAR, []) = [CAR].
  92.  
  93. add_list(CAR, [FIRST]) = [CAR, FIRST].
  94.  
  95. add_list(CAR, [FIRST | REST]) = [CAR, FIRST | REST].
  96.  
  97. nocache(add_list(X,Y)).
  98.  
  99.  
  100. /*------------------- ascent_angle ---------------------*/
  101. nocache(ascent_angle).
  102.  
  103. question(ascent_angle) = 'What is the ascent angle (in
  104. increments of 5 degrees)?'.
  105.  
  106. legalvals(ascent_angle) = [5, 10, 15, 20, 25, 30, 35, 40, 45].
  107.  
  108. /*------------------- ascent_altitude ------------------*/
  109. nocache(ascent_altitude).
  110.  
  111. question(ascent_altitude) = 'To what altitude do you wish to
  112. ascend, in feet? (answer unknown if you prefer to specify angle)'.
  113.  
  114.  
  115. /*------------------- ask_elapsed_time -----------------*/
  116.  
  117. question(ask_elapsed_time) = "How long has the object been
  118. moving?".
  119.  
  120. /*----- <- adjust_altitude(XVEL, YVEL, ASCENT_TIME) ---*/
  121.  
  122. procedure(airplane <- adjust_altitude(XVEL, YVEL, ASCENT_TIME)) = {
  123.    eval SELF <- setslot(x_velocity, XVEL);
  124.    eval SELF <- setslot(y_velocity, YVEL);
  125.    eval SELF <- move(ASCENT_TIME);
  126.    display("New position is: ");
  127.    eval SELF <- print_position;
  128.    }.
  129.  
  130. /*----------------- cargo_to_load -------------------------*/
  131.  
  132. question(cargo_to_load) = 'What cargo do you wish loaded?'.
  133.  
  134. /*----------  <- cargo_unloaded --------------------*/
  135.  
  136. if SELF <- getslot(cargo) = CARGO and
  137.    SELF <- unload(CARGO)
  138. then cargo_plane <- cargo_unloaded.
  139.  
  140. /*----- calculate_ascent_velocity(PLANE, ALTITUDE, TIME) --*/
  141.  
  142. nocache(calculate_ascent_velocity(X, Y, Z)).
  143.  
  144. if PLANE <- getslot(y_position) = Y_POS and
  145.    ALTITUDE - Y_POS = POSITION_CHANGE and
  146.    POSITION_CHANGE/TIME = Y_VEL and
  147.    display(['The required ascent velocity is ', Y_VEL, ' mph.',
  148.    nl])
  149. then calculate_ascent_velocity(PLANE, ALTITUDE, TIME) = Y_VEL.
  150.  
  151. /*----- calculate_descent_velocity(PLANE, ALTITUDE, TIME) --*/
  152.  
  153. nocache(calculate_descent_velocity(X, Y, Z)).
  154.  
  155. if PLANE <- getslot(y_position) = Y_POS and
  156.    ALTITUDE - Y_POS = POSITION_CHANGE and
  157.    POSITION_CHANGE/TIME = Y_VEL and
  158.    display(['The required descent velocity is ', Y_VEL, ' mph.',
  159.    nl])
  160. then calculate_descent_velocity(PLANE, ALTITUDE, TIME) = Y_VEL.
  161.  
  162. /*------------  <- calculate_elapsed_time ------------*/
  163.  
  164. if ask_elapsed_time = TIME
  165. then moving_object <- calculate_elapsed_time = TIME.
  166.  
  167. /*------------------ cos(ANGLE) ---------------------*/
  168. /*
  169.    This is a fact table to look up cos of an angle.
  170.    This is used to compute x and y velocities from
  171.    speed.  This table could be replaced by external
  172.    functions.
  173.    */
  174.  
  175. cos(5) = 1.
  176. cos(10) = 0.98.
  177. cos(15) = 0.97.
  178. cos(20) = 0.94.
  179. cos(25) = 0.91.
  180. cos(30) = 0.89.
  181. cos(35) = 0.82.
  182. cos(40) = 0.77.
  183. cos(45) = 0.71.
  184.  
  185. /*------------ <- create_initialize ------------------*/
  186. /* NOTE: The idea here was to be able to use the airplane rule
  187.    as a super for teh cargo_plane and passenger_plane subclasses.
  188.    But you can only create one of these (either the class or the
  189.    subclass) for each instance, so it doesn't work to do that.
  190.    The subclasses should probably ask crew and position, if it
  191.    matters.  The positions are initialized to 0.
  192.    */
  193.  
  194.  if airplane <- new = NEW and
  195.     NEW <- setslot(name, PLANE_NAME) and
  196.     NEW <- setslot(crew, CREW_SIZE) and
  197.     NEW <- setslot(x_position, XPOS) and
  198.     NEW <- setslot(y_position, YPOS)
  199. then airplane <- create_initialize(PLANE_NAME, CREW_SIZE, XPOS, YPOS).
  200.  
  201. if cargo_plane <- new = NEW and
  202.    plane_name = NAME and
  203.    NEW <- setslot(name, NAME)
  204. then cargo_plane <- create_initialize = NEW.
  205.  
  206. if passenger_plane <- new = NEW and
  207.    plane_name = NAME and
  208.    passenger_capacity = CAPACITY and
  209.    NEW <- setslot(name, NAME) and
  210.    NEW <- setslot(passenger_capacity, CAPACITY)
  211. then passenger_plane <- create_initialize = NEW.
  212.  
  213.  
  214. /*------------ descent_altitude -----------------------*/
  215.  
  216. nocache(descent_altitude).
  217.  
  218. question(descent_altitude) = 'To what altitude do you wish to
  219. descend, in feet? (answer unknown if you prefer to specify angle)'.
  220.  
  221. /*------------------- descent_angle ---------------------*/
  222. nocache(descent_angle).
  223.  
  224. question(descent_angle) = 'What is the descent angle (in
  225. increments of 5 degrees)?'.
  226.  
  227. legalvals(descent_angle) = [5, 10, 15, 20, 25, 30, 35, 40, 45].
  228.  
  229.  
  230. /*--------------- find_desired_plane ------------------*/
  231.  
  232. procedure(find_desired_plane) = {
  233.    TYPE := plane_type;
  234.    find known_plane;
  235.    if known_plane = known {
  236.       find set_legalvals(plane_name(TYPE));
  237.       find plane_name(TYPE);
  238.       forall classinst(TYPE, POSSIBLE_PLANE) {
  239.          NAME := POSSIBLE_PLANE <- getslot(name);
  240.          if plane_name(TYPE) = NAME {
  241.             PLANE :== POSSIBLE_PLANE;
  242.             break;
  243.             };
  244.          };
  245.       }
  246.    else {
  247.       PLANE := TYPE <- create_initialize;
  248.       };
  249.    display(['Plane characteristics are: ', nl]);
  250.    eval PLANE <- printself;
  251.    return PLANE;
  252.    }.
  253.  
  254. /*----------------- <- fly(XVEL, YVEL, TIME) ----------*/
  255.  
  256. procedure(airplane <- fly(XVEL, YVEL, TIME)) = {
  257. /* Note: Could alternately use set_and_print_velocity,
  258.    as in the addendum, with the addition of a TIME
  259.    parameter argument. */
  260.  
  261.    eval SELF <- set_velocity(XVEL, YVEL);
  262.    eval SELF <- move(TIME);
  263.    display("New position is: ");
  264.    eval SELF <- print_position;
  265.    }.
  266.  
  267. /*--------------------- flying_time --------------------*/
  268. nocache(flying_time).
  269.  
  270. question(flying_time) = 'What is the flying time at this
  271. speed, in hours?'.
  272.  
  273. /*--------------------- get_plane_list ---------------*/
  274. nocache(get_plane_list(TYPE)).
  275.  
  276.  
  277. procedure(get_plane_list(TYPE)) = {
  278.    /* NOTE: I'd like to use listof to collect the planes,
  279.       but it doesn't seem to work.
  280.       listof(NAME, classinst(TYPE, PLANE) and
  281.       NAME := PLANE <- getslot(name)) = PLANELIST
  282.       */
  283.    PLANELIST :== [];
  284.    forall classinst(TYPE, PLANE) {
  285.       NAME := PLANE <- getslot(name);
  286.       PLANELIST := add_list(NAME, PLANELIST);
  287.       };
  288.    return PLANELIST;
  289.    }.
  290.  
  291.  
  292.  
  293. /*----------------- <- get_speed --------------------*/
  294.  
  295. procedure(moving_object <- get_speed) = {
  296.    X := SELF <- getslot(x_velocity);
  297.    Y := SELF <- getslot(y_velocity);
  298.    SPEED := sqrt((X*X) + (Y*Y));
  299.    return SPEED;
  300.    }.
  301.  
  302. /*------------------ known_plane ---------------------------*/
  303.  
  304. question(known_plane) = 'Would you like to fly a known plane or
  305. specify a new plane?'.
  306.  
  307. legalvals(known_plane) = [known, new].
  308.  
  309.  
  310. /*---------------- <- load ---------------------------*/
  311.  
  312. procedure(cargo_plane <- load) = {
  313.    CARGO := cargo_to_load;
  314.    OLDCARGO := SELF <- getslot(cargo);
  315.    NEWCARGO := add_list(CARGO, OLDCARGO);
  316.    NAME := SELF <- getslot(name);
  317.    display(["Loading ", NAME, " with ", CARGO, ".  Cargo now is: ",
  318.       NEWCARGO, nl]);
  319.    eval SELF <- setslot(cargo, NEWCARGO);
  320.    reset cargo_to_load;
  321.    }.
  322.  
  323. procedure(passenger_plane <- load) = {
  324.    PASS := passenger_number;
  325.    OLDPASS := SELF <- getslot(number_of_passengers);
  326.    NEWPASS := OLDPASS + PASS;
  327.    NAME := SELF <- getslot(name);
  328.    /* should check that NEWPASS does not exceed passenger
  329.    capacity */
  330.    CAPACITY := SELF <- getslot(passenger_capacity);
  331.    if CAPACITY >= NEWPASS {
  332.       display(["Loading ", NAME, " with ", PASS, "
  333.          passengers. Total passengers is now: ", NEWPASS, nl]);
  334.       eval SELF <- setslot(number_of_passengers, NEWPASS);
  335.       }
  336.    else {
  337.       display(["The passenger capacity for ", NAME, " is ",
  338.       CAPACITY, " which is less than the resulting passenger count of ",
  339.       NEWPASS, ".  The ", PASS, " new passengers were not loaded.", nl]);
  340.       };
  341.    reset passenger_number;
  342.    }.
  343.  
  344. /*----------------- <- move(ELAPSED_TIME) -------------*/
  345.  
  346. procedure(moving_object <- move(ELAPSED_TIME)) = {
  347.    X_POS := SELF <- getslot(x_position);
  348.    Y_POS := SELF <- getslot(y_position);
  349.    X_VEL := SELF <- getslot(x_velocity);
  350.    Y_VEL := SELF <- getslot(y_velocity);
  351.    NEW_X := X_POS + (X_VEL * ELAPSED_TIME);
  352.    NEW_Y := Y_POS + (Y_VEL * ELAPSED_TIME);
  353.    eval SELF <- set_position(NEW_X, NEW_Y);
  354.    ALT := NEW_Y * 5280;
  355.    eval SELF <- setslot(altitude, ALT);
  356.    }.
  357.  
  358. /*-------------------- newlegalvals(plane_name(TYPE)) -------*/
  359. nocache(newlegalvals(plane_name(TYPE))).
  360.  
  361. if get_plane_list(TYPE) = PLANELIST
  362. then newlegalvals(plane_name(TYPE)) = PLANELIST.
  363.  
  364.  
  365. /*---------------------- next_action ----------------*/
  366.  
  367. question(next_action) = 'What is the next action you wish to
  368. take?'.
  369.  
  370. legalvals(next_action) = [load, take_off, ascend, fly, descend,
  371. land, check_position, unload, display_plane, select_plane,
  372. show_planes, stop].
  373.  
  374. /*------------------ passenger_capacity ----------------*/
  375.  
  376. question(passenger_capacity) = 'What is the passenger capacity
  377. of the plane?'.
  378.  
  379. legalvals(passenger_capacity) = integer.
  380.  
  381. /*------------------ passenger_number ------------------*/
  382.  
  383. question(passenger_number) = 'How many new passengers are
  384. there?'.
  385.  
  386. legalvals(passenger_number) = integer.
  387.  
  388. /*--------------------- plane_name ----------------------*/
  389.  
  390. question(plane_name) = 'What is the name of the plane?'.
  391.  
  392. /*------------- plane_name(cargo_plane) ----------------------*/
  393.  
  394. question(plane_name(cargo_plane)) = 'What is the name of the cargo plane?'.
  395.  
  396. legalvals(plane_name(cargo_plane)) = [sea_spray].
  397.  
  398. /*----------- plane_name(passenger_plane) ----------------------*/
  399.  
  400. question(plane_name(passenger_plane)) = 'What is the name of the
  401.    passenger plane?'.
  402.  
  403. legalvals(plane_name(passenger_plane)) = [anemone].
  404.  
  405. /*-------------------- plane_type -----------------------*/
  406.  
  407. question(plane_type) = 'Would you like to fly a cargo or
  408. a passenger plane?'.
  409.  
  410. legalvals(plane_type) = [cargo_plane, passenger_plane].
  411.  
  412. /*----------------------- <- print_position -----------*/
  413.  
  414. procedure(moving_object <- print_position) = {
  415.    XPOS := SELF <- getslot(x_position);
  416.    YPOS := SELF <- getslot(y_position);
  417.    display(["X = ", XPOS, " miles,  Y = ", YPOS, " miles.", nl]);
  418.    }.
  419.  
  420. procedure(airplane <- print_position) = {
  421.    eval SUPER <- print_position;
  422.    ALT := SELF <- getslot(altitude);
  423.    display([" Altitude = ", ALT, " feet.", nl]);
  424.    }.
  425.  
  426. /*--------------- process(ascend, PLANE) ---------------*/
  427.  
  428. procedure(process(ascend, PLANE)) = {
  429.    SPD := speed;
  430.    TIME := ascent-time;
  431.    if ascent_altitude is known {
  432.       ASCENT_ALT := ascent_altitude;
  433.       ALT := ASCENT_ALT/5280;
  434.       Y_VEL := calculate_ascent_velocity(PLANE, ALT, TIME);
  435.       X_VEL := sqrt((SPD * SPD) - (Y_VEL * Y_VEL));
  436.       }
  437.    else {
  438.       if ascent_angle is known {
  439.          ANGLE := ascent_angle;
  440.          COS := cos(ANGLE);
  441.          SIN := sin(ANGLE);
  442.          X_VEL := COS * SPD;
  443.          Y_VEL := SIN * SPD;
  444.          }
  445.       else {
  446.        /* should set some defaults */
  447.           };
  448.        };
  449.    eval PLANE <- adjust_altitude(X_VEL, Y_VEL, TIME);
  450.    }.
  451.  
  452. /*---------------- process(check_position, PLANE) ------*/
  453.  
  454. procedure(process(check_position, PLANE)) = {
  455.    eval PLANE <- print_position;
  456.    }.
  457.  
  458. /*--------------- process(descend, PLANE) ---------------*/
  459.  
  460. procedure(process(descend, PLANE)) = {
  461.    SPD := speed;
  462.    TIME := descent-time;
  463.    if descent_altitude is known {
  464.       DESCENT_ALT := descent_altitude;
  465.       ALT := DESCENT_ALT/5280;
  466.       Y_VEL := calculate_descent_velocity(PLANE, ALT, TIME);
  467.       X_VEL := sqrt((SPD * SPD) - (Y_VEL * Y_VEL));
  468.       }
  469.    else {
  470.       if descent_angle is known {
  471.          ANGLE := descent_angle;
  472.          COS := cos(ANGLE);
  473.          SIN := sin(ANGLE);
  474.          X_VEL := COS * SPD;
  475.          Y_VEL := 0 - SIN * SPD;
  476.          }
  477.       else {
  478.        /* should set some defaults */
  479.           };
  480.        };
  481.    eval PLANE <- adjust_altitude(X_VEL, Y_VEL, TIME);
  482.    }.
  483.  
  484. /*---------------- process(display_plane, PLANE) -------*/
  485.  
  486. procedure(process(display_plane, PLANE)) = {
  487.    eval PLANE <- printself;
  488.    }.
  489.  
  490. /*-------------- process(fly, PLANE) --------------------*/
  491. procedure(process(fly, PLANE)) = {
  492.    SPD := speed;
  493.    F := flying_time;
  494.    eval PLANE <- fly(SPD, 0, F);
  495.    }.
  496.  
  497. /*--------------- process(land, PLANE) ---------------*/
  498.  
  499. procedure(process(land, PLANE)) = {
  500.    Y_POS := PLANE <- getslot(y_position);
  501.    if (Y_POS > 0) {
  502.       set descent_altitude = 0;
  503.       eval process(descend, PLANE);
  504.       reset process(descend, PLANE);
  505.       }
  506.    else {
  507.       display(["A plane must be in the air in order to land.", nl]);
  508.       };
  509.    }.
  510.  
  511.  
  512. /*------------- process(load, PLANE) ---------------------*/
  513.  
  514. procedure(process(load, PLANE)) = {
  515.    eval PLANE <- load;
  516.    }.
  517.  
  518. /*------------ process(show_planes, PLANE) ---------------*/
  519. procedure(process(show_planes, PLANE)) = {
  520.    /* NOTE: What I'd like is a way of finding all the
  521.    subclasses of a class to use with classinst, and
  522.    thus to show the planes in each subclass. */
  523.    TYPE := plane_type;
  524.    NAME := PLANE <- getslot(name);
  525.    PLANES := get_plane_list(TYPE);
  526.    display(['The currently selected plane is ', NAME, '.', nl]);
  527.    display(['The known planes of type ', TYPE, ' are: ', PLANES,
  528.    nl]);
  529.    }.
  530.  
  531. /*------------ process(take_off, PLANE) ------------------*/
  532.  
  533. procedure(process(take_off, PLANE)) = {
  534.    Y_POS := PLANE <- getslot(y_position);
  535.    if (Y_POS == 0) {
  536.       eval process(ascend, PLANE);
  537.       reset process(ascend, PLANE);
  538.       }
  539.    else {
  540.       display(["A plane must be on the ground in order to take
  541.       off.", nl]);
  542.       };
  543.    }.
  544.  
  545. /*-------------- process(unload, PLANE) ------------------*/
  546.  
  547. procedure(process(unload, PLANE)) = {
  548.    eval PLANE <- unload;
  549.    }.
  550.  
  551. /*-------------- <- set_and_print_velocity(XVEL, YVEL) ----*/
  552.  
  553. procedure(airplane <- set_and_print_velocity(XVEL, YVEL)) = {
  554.    NAME := SELF <- getslot(name);
  555.    display(["Setting ", NAME, "'s velocity:   ", nl]);
  556.    eval SELF <- set_velocity(XVEL, YVEL);
  557.    display(["Moving ", NAME, nl]);
  558.    TIME := SELF <- calculate_elapsed_time;
  559.    eval SELF <- move(TIME);
  560.    eval SELF <- printself;
  561.    }.
  562.  
  563. /*------------------- set_legalvals(X) ----------------*/
  564. nocache(set_legalvals(EXPR)).
  565.  
  566. if kbentry(L:legalvals(EXPR) = LIST) and
  567.    newlegalvals(EXPR) = NEWVALS and
  568.    do(add L:legalvals(EXPR) = NEWVALS)
  569. then set_legalvals(EXPR).
  570.  
  571. /*------------ <- set_position(X_POS, Y_POS) -----------*/
  572.  
  573. procedure(moving_object <- set_position(X_POS, Y_POS)) = {
  574.    eval SELF <- setslot(x_position, X_POS);
  575.    eval SELF <- setslot(y_position, Y_POS);
  576.    }.
  577.  
  578. /*----------- <- set_velocity(XVEL, YVEL) ---------------*/
  579.  
  580. procedure(moving_object <- set_velocity(XVEL, YVEL)) = {
  581.    eval SELF <- setslot(x_velocity, XVEL);
  582.    eval SELF <- setslot(y_velocity, YVEL);
  583.    }.
  584.  
  585. /*------------------- simulate --------------------------*/
  586.  
  587. procedure(simulate) = {
  588.    PLANE := find_desired_plane;
  589.    /* loop asking user what they'd like to do next */
  590.    while next_action = ACT {
  591.       if (not ACT == stop) {
  592.          if (ACT == select_plane) {
  593.             reset plane_type;
  594.             reset plane_name;
  595.             reset find_desired_plane;
  596.             PLANE := find_desired_plane;
  597.             reset next_action;
  598.             }
  599.          else{
  600.          eval process(ACT, PLANE);
  601.          reset process(ACT, PLANE);
  602.          reset next_action;
  603.          }
  604.          }
  605.       else {
  606.          display(["Finished simulation.", nl]);
  607.          break; /* exit the while loop */
  608.          }
  609.       }
  610.    }.
  611.  
  612. /*------------------- sin(ANGLE) ---------------------------*/
  613. /*
  614.   This is a fact table to look-up sin for various angles, used
  615.   in determining x and y velocities from speed.  This table
  616.   could be replaced by external functions.
  617.   */
  618.  
  619. sin(5) = 0.09.
  620. sin(10) = 0.17.
  621. sin(15) = 0.26.
  622. sin(20) = 0.34.
  623. sin(25) = 0.42.
  624. sin(30) = 0.5.
  625. sin(35) = 0.57.
  626. sin(40) = 0.64.
  627. sin(45) = 0.71.
  628.  
  629. /*---------------------- speed -----------------------------*/
  630.  
  631. nocache(speed).
  632.  
  633. question(speed) = 'What is your flying speed (in mph)?'.
  634.  
  635. legalvals(speed) = integer.
  636.  
  637.  
  638. /*------------ <- unload --------------------------------*/
  639.  
  640. procedure(cargo_plane <- unload) = {
  641.    NAME := SELF <- getslot(name);
  642.    CARGO := SELF <- getslot(cargo);
  643.    display(["Unloading ", NAME, ".  Cargo is: ", CARGO, nl]);
  644.    eval SELF <- setslot(cargo, []);
  645.    }.
  646.  
  647. procedure(passenger_plane <- unload) = {
  648.    NAME := SELF <- getslot(name);
  649.    PASS := SELF <- getslot(number_of_passengers);
  650.    display(["Unloading ", PASS, " passengers from ", NAME, ".", nl]);
  651.    eval SELF <- setslot(number_of_passengers, 0);
  652.    }.
  653.  
  654. /*----------------- welcome ----------------------------*/
  655.  
  656. if display(['Welcome to the Flight Simulator.', nl])
  657. then welcome.
  658.  
  659. /*----------------- X-time -----------------------------*/
  660. nocache(X-time).
  661.  
  662. question(X-time) = ['What is the time for ', X, ', in
  663. hours?'].
  664.  
  665. /*----------------- x_velocity --------------------------*/
  666.  
  667. nocache(x_velocity).
  668.  
  669. question(x_velocity) = 'What is the x velocity, in mph?'.
  670.  
  671. /*------------------ y_velocity --------------------------*/
  672.  
  673. nocache(y_velocity).
  674.  
  675. question(y_velocity) = 'What is the y velocity, in mph? (positive
  676. to ascend, negative to descend)'.
  677.  
  678.  
  679.  
  680.